<template>
  <div id="calendar" class="bg-cf cp" :class="{ change: isChange }">
    <!-- 年份 月份 -->
    <div class="year-month">
      <div class="year-month_left">
        <span class="top-time">{{ currentMonth }}月</span>
        <ul>
          <li>周{{ weekdays[newWeek] }}</li>
          <li>{{ currentYear }}年</li>
        </ul>
      </div>
      <div class="year-month_right">
        <!-- <x-icon
          @click="addSchedule"
          type="ios-plus-empty"
          size="30"
          class="i-plus-empty"
        ></x-icon> -->

        <el-icon @click="leftSliding"><arrow-left-bold /></el-icon>
        <el-icon @click="rightSliding"><arrow-right-bold /></el-icon>
        <!-- <i @click="leftSliding" class="el-icon-arrow-left fz-26"></i> -->
        <!-- <i class="el-icon-arrow-right fz-26" @click="rightSliding"></i> -->
      </div>
    </div>
    <!-- 星期 -->
    <ul class="weekdays">
      <li v-for="(vo, index) in weekdays" v-text="vo" :key="index"></li>
    </ul>
    <!-- 日期 -->
    <ul
      class="days"
      :class="{
        fadeOut: fadeOut,
        fadeIn: fadeIn,
        fadeOutR: fadeOutR,
        fadeInR: fadeInR
      }"
      @touchstart="allTouchStart"
      @touchend="allTouchEnd"
      @touchstart.stop="touchStart"
      @touchend.stop="touchEnd"
    >
      <!-- 核心 v-for循环 每一次循环用<li>标签创建一天 -->
      <li
        v-for="(dayobject, index) in days"
        :class="{ weekend: index % 7 === 0 || (index + 1) % 7 === 0 }"
        :key="index"
      >
        <!--本月-->
        <!--如果不是本月 改变类名加灰色-->
        <div
          v-if="dayobject.day.getMonth() + 1 !== currentMonth"
          @click="otherMonth(dayobject.day.getDate())"
          class="other-month"
        >
          {{ dayobject.day.getDate() }}
        </div>
        <!--如果是本月 还需要判断是不是这一天-->
        <div v-else class="everyDay">
          <!--今天 同年同月同日-->
          <div
            @click="
              getDayMessage(currentYear, currentMonth, dayobject.day.getDate())
            "
            v-if="
              dayobject.day.getFullYear() === new Date().getFullYear() &&
              dayobject.day.getMonth() === new Date().getMonth() &&
              dayobject.day.getDate() === new Date().getDate()
            "
            :class="{ otherday: dayobject.day.getDate() === otherDay }"
          >
            {{ dayobject.day.getDate() }}
          </div>
          <div
            class="fz-12"
            :class="{ otherday: dayobject.day.getDate() === otherDay }"
            v-else
            @click="
              getDayMessage(currentYear, currentMonth, dayobject.day.getDate())
            "
          >
            {{ dayobject.day.getDate() }}
          </div>
          <div
            :class="{
              circle: dayobject.status === '3',
              o: dayobject.status === '2'
            }"
          ></div>
        </div>
      </li>
    </ul>
    <!--背景色-->
    <div class="background" :class="{ change: isChange }">
      <div
        v-for="(value, index) in 5"
        :class="{ dbg: index % 2 === 0, lbg: index % 2 !== 0 }"
        :key="index"
      ></div>
    </div>
  </div>
</template>

<script>
import { ArrowLeftBold, ArrowRightBold } from '@element-plus/icons'
export default {
  name: 'Calendar',
  components: {
    ArrowLeftBold,
    ArrowRightBold
  },
  data() {
    return {
      currentDay: 1,
      currentMonth: 1,
      currentYear: 1970,
      currentWeek: 1,
      newWeek: 1,
      days: [],
      weekdays: ['日', '一', '二', '三', '四', '五', '六'],
      // 上下滑动的鼠标位置
      positionSX: '',
      positionEX: '',
      positionSY: '',
      positionEY: '',
      isChange: false,
      // 左右滑动动画的初始状态
      show: true,
      fadeOut: false,
      fadeIn: false,
      fadeOutR: false,
      fadeInR: false,
      monthList: [],
      status: '',
      otherDay: ''
    }
  },
  created() {
    this.initData(null)
  },
  emit: ['change'],
  methods: {
    getDayMessage(y, m, d) {
      this.getCurrentWeek(y, m, d)
      const str = this.formatDate(y, m, d)
      this.$emit('change', str, m, d)
      this.otherDay = d
    },
    getCurrentWeek(y, m, d) {
      const w = `${y}-${m}-${d}`
      const weekArr = w.split('-')
      const weeks = new Date(weekArr[0], parseInt(weekArr[1] - 1), weekArr[2])
      this.newWeek = weeks.getDay()
    },
    otherMonth(day) {
      if (day < 15) {
        this.rightSliding()
      } else if (day > 15) {
        this.leftSliding()
      }
    },
    //向下滑监听坐标
    allTouchStart(e) {
      //开始x轴坐标
      this.positionSX = e.changedTouches[0].clientX
      //开始y轴坐标
      this.positionSY = e.changedTouches[0].clientY
    },
    allTouchEnd(e) {
      //结束x轴坐标
      this.positionEX = e.changedTouches[0].clientX
      //结束y轴坐标
      this.positionEY = e.changedTouches[0].clientY
      const distanceY = this.positionEY - this.positionSY
      const distanceX = this.positionSX - this.positionEX
      //判断滑动的方向
      if (distanceY < -30 && Math.abs(distanceY) > Math.abs(distanceX)) {
        this.isChange = true
      }
      if (distanceY > 30 && Math.abs(distanceY) > Math.abs(distanceX)) {
        this.isChange = false
      }
    },

    //监听左右滑动坐标
    touchStart(e) {
      //开始x轴坐标
      this.positionSX = e.changedTouches[0].clientX
      //开始y轴坐标
      this.positionSY = e.changedTouches[0].clientY
    },
    touchEnd(e) {
      this.show = !this.show
      //结束x轴坐标
      this.positionEX = e.changedTouches[0].clientX
      //结束y轴坐标
      this.positionEY = e.changedTouches[0].clientY
      const distanceY = this.positionEY - this.positionSY
      const distanceX = this.positionSX - this.positionEX
      //判断滑动 的方向
      if (distanceX > 30 && Math.abs(distanceY) < Math.abs(distanceX)) {
        this.rightSliding()
      }
      if (distanceX < -30 && Math.abs(distanceY) < Math.abs(distanceX)) {
        this.leftSliding()
      }
    },
    //向右滑动
    rightSliding() {
      this.pickNext(this.currentYear, this.currentMonth)
      this.fadeOut = true
      this.fadeIn = false
      this.fadeInR = false
      this.fadeOutR = false
      setTimeout(() => {
        this.fadeIn = true
        this.fadeOut = false
        this.fadeOutR = false
        this.fadeInR = false
      }, 300)
    },
    //向左滑动
    leftSliding() {
      this.pickPre(this.currentYear, this.currentMonth)
      this.fadeOutR = true
      this.fadeInR = false
      this.fadeOut = false
      this.fadeIn = false
      setTimeout(() => {
        this.fadeInR = true
        this.fadeOutR = false
        this.fadeOut = false
        this.fadeIn = false
      }, 300)
    },
    initData(cur) {
      let date
      if (cur) {
        date = new Date(cur)
      } else {
        const now = new Date()
        const t = this.formatDate(now.getFullYear(), now.getMonth(), 1)
        const d = new Date(t)
        d.setDate(35)
        date = new Date(this.formatDate(d.getFullYear(), d.getMonth() + 1, 1))
      }

      this.currentDay = date.getDate()
      this.currentYear = date.getFullYear()
      this.currentMonth = date.getMonth() + 1
      this.currentWeek = date.getDay()
      if (!cur || !this.otherDay) {
        this.otherDay = new Date().getDate()
      }
      const str = this.formatDate(
        this.currentYear,
        this.currentMonth,
        this.currentDay
      )
      this.days.length = 0
      //初始化本周
      for (let i = this.currentWeek; i >= 0; i--) {
        const d = new Date(str)
        d.setDate(d.getDate() - i)
        const dayobject = {} //用一个对象包装Date对象 以便为以后预定功能添加属性
        dayobject.day = d
        dayobject.status = ''
        this.days.push(dayobject) //将日期放入data 中的days数组 供页面渲染使用
      }
      //其他周
      for (let i = 1; i <= 34 - this.currentWeek; i++) {
        const d = new Date(str)
        d.setDate(d.getDate() + i)
        const dayobject = {}
        dayobject.day = d
        dayobject.status = ''
        this.days.push(dayobject)
      }
      //选中日期在其他月份是否超出最大日期判断
      const arr = []
      for (let j = 0, length = this.days.length; j < length; j++) {
        if (this.days[j].day.getMonth() + 1 === this.currentMonth) {
          arr.push(this.days[j].day.getDate())
        }
      }
      const maxDate = Math.max.apply(null, arr)
      if (this.otherDay > maxDate) {
        this.otherDay = maxDate
      }

      this.getDayMessage(this.currentYear, this.currentMonth, this.otherDay)
    },
    //     上个月信息
    pickPre(year, month) {
      const d = new Date(this.formatDate(year, month, 1))
      d.setDate(0)
      this.initData(this.formatDate(d.getFullYear(), d.getMonth() + 1, 1))
    },
    // 下个月信息
    pickNext(year, month) {
      const d = new Date(this.formatDate(year, month, 1))
      d.setDate(35)
      this.initData(this.formatDate(d.getFullYear(), d.getMonth() + 1, 1))
    },
    // 补零处理
    formatDate(year, month, day) {
      let y = year
      let m = month
      if (m < 10) m = '0' + m
      let d = day
      if (d < 10) d = '0' + d
      return y + '-' + m + '-' + d
    }
  }
}
</script>

<style lang="less" scoped>
#calendar {
  width: 100%;
  height: auto;
  margin: 0 auto;
  transition: all 0.5s;
  overflow: hidden;
  background: #fff;
  .change {
    height: 250px !important;
  }
  .year-month {
    height: 80px;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-around;
    .year-month_left {
      height: 100%;
      width: 80%;
      font-size: 18px;
      padding-left: 14px;
      display: flex;
      align-items: center;
      .top-time {
        color: #333;
        font-size: 26px;
        font-weight: 500;
        margin-right: 10px;
      }
      ul {
        display: flex;
        flex-direction: column;
        li {
          color: #ccc;
          font-size: 14px;
        }
      }
    }
    .year-month_right {
      height: 100%;
      width: 20%;
      display: flex;
      align-items: center;
      justify-content: flex-end;
      padding-right: 12px;
      .i-plus-empty {
        fill: #f18d2f;
      }
    }
  }
  .weekdays {
    margin: 0;
    height: 40px;
    font-size: 14px;
    display: flex;
    flex-wrap: wrap;
    color: #999;
    justify-content: space-around;
    li {
      display: inline-block;
      width: 13.6%;
      text-align: center;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }
  .days {
    height: 210px;
    padding: 0;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
    overflow: hidden;
    position: relative;
    li {
      list-style-type: none;
      display: inline-block;
      height: 42px;
      width: 13.4%;
      text-align: center;
      font-size: 16px;
      color: #000;
      position: relative;
      .active {
        border-radius: 50%;
        background: rgba(81, 152, 254, 0.3);
        color: #5198fe;
        width: 30px;
        height: 30px;
        margin: auto;
        display: flex;
        justify-content: center;
        align-items: center;
      }
      .other-month {
        width: 30px;
        height: 30px;
        margin: auto;
        display: flex;
        justify-content: center;
        align-items: center;
        color: #a2a2a2;
      }
      .everyDay {
        width: 30px;
        height: 30px;
        margin: auto;
        display: flex;
        justify-content: center;
        align-items: center;
      }
      .circle {
        width: 4px;
        height: 4px;
        border-radius: 50%;
        background-color: #f2553d;
        position: absolute;
        bottom: 6px;
        left: 48%;
      }
      .o {
        width: 4px;
        height: 4px;
        border-radius: 50%;
        border: 1px solid #f2553d;
        position: absolute;
        bottom: 1px;
        left: 49%;
      }
      .otherday {
        width: 28px;
        height: 28px;
        margin: auto;
        display: flex;
        justify-content: center;
        align-items: center;
        border-radius: 50%;
        background: rgba(81, 152, 254, 0.3);
        color: #5198fe;
      }
    }
  }
  .fadeOut {
    animation-name: fadeOut;
    animation-duration: 0.5s;
    animation-timing-function: ease-in-out;
  }
  .fadeOutR {
    animation-name: fadeOutR;
    animation-duration: 0.5s;
    animation-timing-function: ease-in-out;
  }
  .fadeIn {
    animation-name: fadeIn;
    animation-duration: 0.5s;
    animation-timing-function: ease-in-out;
  }
  .fadeInR {
    animation-name: fadeInR;
    animation-duration: 0.5s;
    animation-timing-function: ease-in-out;
  }
  .background {
    position: absolute;
    top: 100px;
    height: 211px;
    width: 100%;
    z-index: -1;
    overflow: hidden;
    transition: all 0.5s;
    .dbg {
      background-color: #e1e1e1;
      height: 42.2px;
    }
    .lbg {
      background-color: #d5d5d5;
      height: 42.2px;
    }
  }
}

@keyframes fadeOut {
  0% {
    transform: translateX(0);
    opacity: 1;
  }
  100% {
    transform: translateX(-100%);
    opacity: 0;
  }
}
@keyframes fadeIn {
  0% {
    transform: translateX(100%);
    opacity: 0;
  }
  100% {
    transform: translateX(0);
    opacity: 1;
  }
}
@keyframes fadeOutR {
  0% {
    transform: translateX(0);
    opacity: 1;
  }
  100% {
    transform: translateX(100%);
    opacity: 0;
  }
}
@keyframes fadeInR {
  0% {
    transform: translateX(-100%);
    opacity: 0;
  }
  100% {
    transform: translateX(0);
    opacity: 1;
  }
}
</style>
